/**
 * File:    AmbigousZoneExtractor.h
 * Author:  Bui Quang Anh
 * Email:   quang_anh.bui@univ-lr.fr
 * Version: 1.0
 * 
 * DESCRIPTION:
 * Header file for class AmbigousZoneExtractor.
 * Provide algorithms for extraction of ambigous zones in image
 * 
 * CHANGE HISTORY:
 * (23/10/2011 12:55) File first time created - BUI Quang Anh
 */
#pragma once
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <stack>
#include <list>
#include <set>
#include <utility>
#include <sstream>

#include <opencv.hpp>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>

#include "Structures.h"

using namespace std;

class AmbigousZoneExtractor
{
public:
	/*----------- Properties -----------*/

	/*----------- Functions -----------*/
	
	// Constructor
	AmbigousZoneExtractor(void);
	// Destructor
	~AmbigousZoneExtractor(void);

	// Run algorithm
	// @input_filename: Name of source image file
	int AmbigousZoneExtractor::run(const char* input_filename, vector<StrokeNode*> &stroke_graph, IplImage** ambigous_zones_map);

	// Get estimated stroke width
	int getEstimatedStrokeWidth();
	
private:
	/*----------- Properties -----------*/
	int estimated_stroke_width;
	/*----------- Functions -----------*/

	// Find candidate fork points based on thinned image
	// @thinned_image: source image
	// @connected_feature_points_sets: list of the set of feature points that is in the same connected region
	void FindFeaturePoints(IplImage* thinned_image, vector<set<FeaturePoint>> &connected_feature_points_sets);

	// Analyse a point in thinned image to find out this point is fork point, end point or normal point
	// Return 1: End point
	// Return > 1: Fork point. Value return is Nb
	// Return 0: Normal point
	int AnalysePoint(IplImage* thinned_image, int x, int y);

	// Find spurious fork points
	// @source_image: original image
	// @thinned_image: thinned image
	// @connected_feature_points_sets: list of the set of feature points that is in the same connected region
	// @S1: set of Spurious Candidate Fork Points returned
	void FindSpuriousCandidateForkPoints(IplImage* source_image, IplImage* thinned_image, const vector<set<FeaturePoint>> &connected_feature_points_sets, set<FeaturePoint> &S1);

	// Visualyze feature points
	// @image_name: name of output image file 
	// @thinned_image: thinned image 
	// @connected_feature_points_sets: list of the set of feature points that is in the same connected region
	// @S1: set of spurious candidate fork points
	void VisualyzeFeaturePoint(const char* image_name, IplImage* thinned_image,const vector<set<FeaturePoint>> &connected_feature_points_sets, const set<FeaturePoint> &S1);

	// Detect ambigous zones
	// @input_filename: original source filename
	// @stroke_graph: Output graph of sub-strokes and ambigous zones
	// Return: Ambigous zones map
	IplImage* DetectAmbigousZones(const char* input_filename, vector<StrokeNode*> &stroke_graph, const vector<set<FeaturePoint>> &Sa);
};

